# -*- coding:utf-8 -*-

# @Time : 2022/11/22 15:11
# @Author : 快乐的小猴子
# @Version : 
# @Function : 


import requests
import os
import time
from lxml import etree
from YouMeiPics.conf import settings
from YouMeiPics.conf.SetProxies import SetProxies


class TestSpider:
    """
    公共类    包含发送请求函数
    """

    def send(self, url):
        '''
        发送请求, 获取响应数据
        :param url:
        :return:
        '''
        # resp = requests.get(url=url, headers=settings.headers, proxies=get_proxy_ip.get_proxy_ip())
        resp = requests.get(url=url, headers=settings.headers, proxies=SetProxies().get_proxies())
        resp.encoding = 'utf-8'
        return resp.text

    def down_pics_send(self, name, url, pics_path):
        '''
        下载单页图片
        :param name:
        :param url:
        :return:
        '''
        try:
            # resp = requests.get(url, headers=settings.headers, proxies=get_proxy_ip.get_proxy_ip())
            resp = requests.get(url=url, headers=settings.headers, proxies=SetProxies().get_proxies())
            with open('{}{}.jpg'.format(pics_path, name), 'wb') as fp:
                fp.write(resp.content)
        except Exception as e:
            print(e)

    def get_son_urls(self, html):
        '''
        获取页面中的下级标题和url地址信息
        :param html:
        :return:
        '''
        et = etree.HTML(html)
        # 二级标题和url
        sec_pic_names = et.xpath('//ul[@class="clearfix"]/li[@class="nav-li  on"]/a/text()')
        sec_pic_urls = et.xpath('//ul[@class="clearfix"]/li[@class="nav-li  on"]/a/@href')
        thr_pic_names = et.xpath('//ul[@class="clearfix"]/li[@class="nav-li  on"]/div[@class="sonnav"]/a/text()')
        thr_pic_urls = et.xpath('//ul[@class="clearfix"]/li[@class="nav-li  on"]/div[@class="sonnav"]/a/@href')
        return sec_pic_names, sec_pic_urls, thr_pic_names, thr_pic_urls

    def handle_son_datas(self, html):
        '''
        处理下级标题和url数据
        :param html:
        :return:
        '''
        sec_pic_names, sec_pic_urls, thr_pic_names, thr_pic_urls = self.get_son_urls(html)
        # 处理二级标题和url
        sec_data_list = []
        for i in range(0, len(sec_pic_names)):
            sec_data_dics = {}
            sec_data_dics[str(i + 1)] = (sec_pic_names[i], settings.url + sec_pic_urls[i])
            sec_data_list.append(('1', sec_data_dics))
        for j in range(0, len(thr_pic_names)):
            thr_data_dics = {}
            thr_data_dics[str(j + 1)] = (thr_pic_names[j], settings.url + thr_pic_urls[j])
            sec_data_list.append(('2', thr_data_dics))
        return sec_data_list

    def if_levl(self, data_list):
        '''
        判断是否为子1级数据，否则为子2级数据
        :param data_list:
        :return:
        '''
        sec_datas = []
        thr_datas = []
        print(data_list)
        for data in data_list:
            if data[0] == '1':
                sec_datas.append(data[1])
            else:
                thr_datas.append(data[1])
        return sec_datas, thr_datas

    def get_fir_view_cont(self, sec_datas):
        '''
        获取子一级展示数据信息，即向用户展示的第一级数据
        :param sec_datas:
        :return:
        '''
        show_contents1 = ''
        num_list1 = []
        for i in range(0, len(sec_datas)):
            # 处理展示的第一级字符串提示信息
            pic_type_name = list(sec_datas[i].values())[0][0]
            show_cont1 = str(list(sec_datas[i].keys())[0]) + '\t' + str(pic_type_name) + '\n'
            show_contents1 += show_cont1
            # 对应的序号放入列表，判断用户输入的序号对应的数据是否存在
            num_list1.append(str(list(sec_datas[i].keys())[0]))
        return show_contents1, num_list1

    def get_pic_nm_url(self, temp_cont2_list, in_seq2):
        '''
        获取图片的标题和url地址信息
        :param temp_cont2_list:
        :param in_seq2:
        :return:
        '''
        for k in range(0, len(temp_cont2_list)):
            if in_seq2 != list(temp_cont2_list[k].keys())[0]:
                continue
            else:
                pic_name = temp_cont2_list[k][in_seq2][0]
                pic_url = temp_cont2_list[k][in_seq2][1]
                return pic_name, pic_url

    def handle_rela(self, in_seq, thr_datas):
        '''
        处理获取到的数据，拼接二级展示数据字符串
        :param in_seq:
        :param thr_datas:
        :return:
        '''
        show_contents2 = ''
        num_list2 = []
        temp_cont2_list = []
        print('thr_datas', thr_datas)
        for j in settings.rel_list[int(in_seq)]:
            show_cont2 = str(j) + '\t' + str(thr_datas[j - 1]) + '\n'
            # print(show_cont2)
            show_contents2 += show_cont2
            num_list2.append(j)
            temp_cont2_list.append(thr_datas[j - 1])
        return show_contents2, num_list2, temp_cont2_list

    def get_sec_view_cont(self, thr_datas, in_seq):
        '''
        获取子二级展示数据信息，即向用户展示的第二级数据
        :param thr_datas:
        :param in_seq:
        :return:
        '''
        for rel in list(settings.rel_list.keys()):
            if in_seq == str(rel):
                show_contents2, num_list2, temp_cont2_list = self.handle_rela(in_seq, thr_datas)
                print('temp_cont2_list', temp_cont2_list)
                while True:
                    try:
                        in_seq2 = input('{}请输入要下载的图片风格对应的序号(q/Q退出): '.format(show_contents2)).strip()
                        if in_seq2.upper() == 'Q':
                            # break
                            continue
                        pic_name, pic_url = self.get_pic_nm_url(temp_cont2_list, in_seq2)
                        return pic_name, pic_url, in_seq2
                    except Exception as e:
                        print(e)

    def get_page_num(self, html):
        '''
        获取总页码
        :param html:
        :return:
        '''
        et = etree.HTML(html)
        page_num = et.xpath('//div[@id="pageNum"]/a[3]/@href')[0].split('_')[-1].split('.')[0]
        return page_num

    def verf_dir(self, pic_type_name):
        '''
        校验图片存储路径是否存在，不存在则创建
        :return:
        '''
        pics_path = os.getcwd() + '\\pictures\\{}\\'.format(pic_type_name)
        if not os.path.exists(pics_path):
            os.makedirs(pics_path)
        return pics_path

    def get_exist_pics_name(self, pic_path):
        '''
        获取图片文件夹中已经存在的图片名称
        :param pic_path:
        :return:
        '''
        pic_names = os.listdir(pic_path)
        pic_name_list = []
        for name in pic_names:
            pic_name = name.strip()[:-4]
            pic_name_list.append(pic_name)
        return pic_name_list

    def get_pics(self, html, pic_type_name):
        '''
        一页图片下载
        :param html:
        :return:
        '''
        et = etree.HTML(html)
        big_pic_name = et.xpath('//div[@class="tushuowarp"]//dl/dd[@class="ts-l-l-pic"]/a/img/@alt')
        big_pic_url = et.xpath('//div[@class="tushuowarp"]//dl/dd[@class="ts-l-l-pic"]/a/img/@data-original')
        for i in range(0, len(big_pic_name)):
            print('{} 正在下载中......'.format(big_pic_name[i]))
            pics_path = self.verf_dir(pic_type_name)
            pic_name_list = self.get_exist_pics_name(pics_path)
            if big_pic_name[i].strip() in pic_name_list:
                print('{} 已经存在！！！'.format(big_pic_name[i]))
                continue
            else:
                self.down_pics_send(big_pic_name[i], big_pic_url[i], pics_path)
                time.sleep(0.5)
                print('{} {} 下载完成 !'.format(i + 1, big_pic_name[i]))

    def more_pics_down(self, page_num, pic_type_name, in_seq2):
        '''
        所有图片页数据下载
        :param page_num:
        :param html:
        :return:
        '''
        for num in range(1, int(page_num) + 1):
            try:
                next_url = '{}/tushuotianxia/{}/index_{}.htm'.format(settings.url, settings.pic_tstx_urls[in_seq2],
                                                                     str(num))
                html = self.send(next_url)
                self.get_pics(html, pic_type_name)
            except Exception as e:
                print(e)
            print('>>>>>> 第 {} 页 图片下载完成 0_0 !!! >>>>>>>'.format(num))

    def main_luoji(self, data_list):
        sec_datas, thr_datas = self.if_levl(data_list)
        show_contents1, num_list1 = self.get_fir_view_cont(sec_datas)
        while True:
            in_seq = input('{}请输入要下载的图片类型对应的序号(q/Q退出): '.format(show_contents1)).strip()
            if in_seq.upper() == 'Q':
                break
            if in_seq not in num_list1:
                print('您输入的序号不正确，请重新输入！！！')
            else:
                # self.get_sec_view_cont(thr_datas, in_seq)
                pic_name, pic_url, in_seq2 = self.get_sec_view_cont(thr_datas, in_seq)
                print(pic_name, pic_url)

                """ 图说天下 """
                html = self.send(pic_url)
                # # 单页下载
                # self.get_pics(html, pic_name)
                # # 所有页下载
                page_num = self.get_page_num(html)
                self.more_pics_down(page_num, pic_name, in_seq2)


ts = TestSpider()
html = ts.send(settings.url)
data_list = ts.handle_son_datas(html)
ts.main_luoji(data_list)
